package com.mappn.backup;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.Dialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.mappn.backup.contact.ContactTFileStore;
import com.mappn.backup.contact.ContactTVo;
import com.mappn.backup.util.Const;
import com.mappn.backup.util.PrefUtil;
import com.mappn.backup.util.Utils;

public class Main extends Activity implements OnClickListener {
	private static final String TAG = "Main";
	Session session = null;
	private static Process process = null;
	private Button btnBackup = null;
	private Button btnRestore = null;
	private TextView tvBackup = null;
	private TextView tvRestore = null;
	private TextView tvLastBackTime = null;
	private MyPb pd;
	private static final int BACKUP_OVER = 1;
	private static final int BACKUP_ADD = BACKUP_OVER + 1;
	private static final int BACKUP_ERROR = BACKUP_ADD + 1;
	private static final int BACKUP_CANCEL = BACKUP_ERROR + 1;
	private static final int RESTORE_OVER = BACKUP_CANCEL + 1;
	private static final int RESTORE_ADD = RESTORE_OVER + 1;
	private static final int RESTORE_ERROR = RESTORE_ADD + 1;
	private static final int RESTORE_CANCEL = RESTORE_ERROR + 1;
	private static final int BACKUP_BEGAIN = RESTORE_CANCEL + 1;
	private static final int BACKUP_BEGAIN_EXCEPT = BACKUP_BEGAIN + 1;
	private static final int PD_BACKUP = 1;
	private static final int PD_RESTORE = PD_BACKUP + 1;
	private static final int PD_CANCEL = PD_RESTORE + 1;
	private static final int PD_RUNGNING = PD_CANCEL + 1;
	private boolean IsOnlyContact = false;
	public static boolean isRunning = false;
	public  int num=0;
	
	private int mContactCount = 0;
	private boolean mIsBackUp = true;
	private List<ContactTVo> contactFiles;
	private int mCurreantRestore = 0;

	/** 用于存放安装的应用列表(pkg,apkpath) */
	private HashMap<String, String> mApkPath = null;
	/** 用于存放已备份的应用列表(pkg) */
	private String[] mApkBackPkg = null;
	private List<String> mApkNeedRestorePkg = null;
	private Thread thread;
	private int mCurrent = 0;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		isRunning = true;
		setContentView(R.layout.test);
		showDialog(PD_RUNGNING);
		btnBackup = (Button) findViewById(R.id.btnBackup);
		btnBackup.setOnClickListener(this);
		btnRestore = (Button) findViewById(R.id.btnRestore);
		btnRestore.setOnClickListener(this);
		tvBackup = (TextView) findViewById(R.id.tvBackup);
		tvRestore = (TextView) findViewById(R.id.tvRestore);
		tvLastBackTime = (TextView) findViewById(R.id.tvLastBackTime);
		initAlarm();
		new Thread() {

			@Override
			public void run() {
				process = Session.getInstance().getProcess();
				if (Utils.testSu(process)) {
					System.out.println("get su");
					IsOnlyContact = false;
				} else {
					// TODO 木有su权限 提示只能备份联系人
					IsOnlyContact = true;
				}
				handler.sendEmptyMessage(BACKUP_BEGAIN);
			}

		}.start();

	}

	/**
	 * 绑定AlarmManager
	 * */
	private void initAlarm() {
		AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
		Intent intent = new Intent(this, AlarmReceiver.class);
		intent.setAction(Const.MY_ALARM_ACTION);
		PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
				intent, 0);
		alarmManager.cancel(pendingIntent);
		long repeatTime = PrefUtil.getNotiBackup(getApplicationContext());
		// 开始时间
		long firstime = SystemClock.elapsedRealtime() + repeatTime;
		alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
				firstime, repeatTime, pendingIntent);
	}

	@Override
	protected void onResume() {
		super.onResume();

		long backupTime = PrefUtil.getLastBackup(getApplicationContext());
		if (backupTime != 0) {
			Date date = new Date(backupTime);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			tvLastBackTime.setText("上次备份时间：" + sdf.format(date));
		} else {
			tvLastBackTime.setText("无法获取上次备份时间，建议您立即备份");
		}
		// 安装的应用列表
		mApkPath = Utils.getAllApkPath(getApplicationContext());
		tvRestore.setText("本地共有" + mApkPath.size() + "款应用");

		// 已备份的应用列表
		File file = new File(Const.APK_FOLDER);
		if (file.exists()) {
			mApkBackPkg = file.list();
			for (int i = 0; i < mApkBackPkg.length; i++) {
				String apkPkg = mApkBackPkg[i].split(".tar")[0];
				mApkBackPkg[i] = apkPkg;
				System.out.println("已备份: " + apkPkg);
			}
		}
		if (mApkBackPkg == null) {
			tvBackup.setText("已备份了0款应用");
		} else {
			mApkNeedRestorePkg = new ArrayList<String>();
			for (int i = 0; i < mApkBackPkg.length; i++) {
				String packageName = mApkBackPkg[i];
				// 如果已安装应用列表中包含已备份的应用，则不安装
				if (!mApkPath.containsKey(packageName)) {
					mApkNeedRestorePkg.add(packageName);
				}
			}

			tvBackup.setText("已备份了" + mApkBackPkg.length + "款应用，其中有"
					+ mApkNeedRestorePkg.size() + "款未安装需要恢复");
			// if (mApkNeedRestorePkg.size() == 0) {
			// btnRestore.setClickable(false);
			// }
		}
	}

	private class BackupThread extends Thread {

		@Override
		public void run() {
			super.run();
			Set<String> pathSet = mApkPath.keySet();

			// 备份前检查文件夹是否存在，如果存在，则删除
			File file = new File(Const.APP_FOLDER);
			if (file.exists()) {
				Utils.deleteFile(file);
			}

			// 备份联系人
			List<ContactTVo> contactFiles = new ArrayList<ContactTVo>();

			ContentResolver contentResolver = getContentResolver();
			Cursor cursor = contentResolver.query(
					ContactsContract.Contacts.CONTENT_URI, null, null, null,
					null);
			mContactCount = cursor.getCount();
			System.out.println("BackupThread size:" + cursor.getCount());
			while (cursor.moveToNext()) {

				ContactTVo contactVo = new ContactTVo();

				// 获取手机号
				int contactId = cursor.getInt(cursor
						.getColumnIndex(ContactsContract.Contacts._ID));
				String name = cursor
						.getString(cursor
								.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
				Cursor data = getContentResolver().query(
						ContactsContract.Data.CONTENT_URI,
						null,
						ContactsContract.CommonDataKinds.Phone.CONTACT_ID
								+ " = " + contactId, null, null);

				String phone = "";
				Log.d(TAG, "size = " + data.getColumnCount());

				while (data.moveToNext()) {
					String mimeType = data.getString(data
							.getColumnIndex(ContactsContract.Data.MIMETYPE));
					Log.d(TAG, "mimeType :" + mimeType);
					Log
							.d(
									TAG,
									"ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE :"
											+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
					Log.d(TAG, "phone 1 :" + phone);
					if (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
							.equals(mimeType)) {
						if (phone.equals("")) {
							phone = data
									.getString(data
											.getColumnIndex(ContactsContract.Data.DATA1));
						} else {
							phone = data
									.getString(data
											.getColumnIndex(ContactsContract.Data.DATA1))
									+ "," + phone;
						}
						if (phone.equals(""))
							Log
									.d(
											TAG,
											"号码类型："
													+ data
															.getString(data
																	.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)));
						Log.d(TAG, "phone 2 :" + phone);
					}
					Log.d(TAG, "phone 3 :" + phone);
				}
				data.close();
				contactVo.setName(name);
				contactVo.setPhone(phone);

				// 获取邮箱
				Cursor emails = getContentResolver().query(
						ContactsContract.CommonDataKinds.Email.CONTENT_URI,
						null,
						ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
								+ contactId, null, null);
				String emailValue = "";
				while (emails.moveToNext()) {
					String emailType = emails
							.getString(emails
									.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
					emailValue = emails
							.getString(emails
									.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
					Log.d(TAG, "email类型：" + emailType);
					Log.d(TAG, "email：" + emailValue);
				}
				emails.close();
				contactVo.setEmail(emailValue);

				// 获取联系人地址
				Cursor address = getContentResolver()
						.query(
								ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
								null,
								ContactsContract.CommonDataKinds.Phone.CONTACT_ID
										+ "=" + contactId, null, null);
				String street = "";
				String city = "";
				String region = "";
				String postCode = "";
				String formatAddress = "";
				while (address.moveToNext()) {
					street = address
							.getString(address
									.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
					city = address
							.getString(address
									.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
					region = address
							.getString(address
									.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
					postCode = address
							.getString(address
									.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
					formatAddress = address
							.getString(address
									.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));
					Log.d(TAG, "address street :" + street);
					Log.d(TAG, "address city :" + city);
					Log.d(TAG, "address region :" + region);
					Log.d(TAG, "address postCode :" + postCode);
					Log.d(TAG, "address formatAddress :" + formatAddress);
				}
				address.close();
				// map.put(key, value)
				contactVo.setAddress(formatAddress);

				contactFiles.add(contactVo);
				contactFiles.add(contactVo);
				Log.d(TAG, name + "phone :[" + phone + "]");
				ContactTFileStore
						.insertToSd(getApplicationContext(), contactVo);
				handler.sendEmptyMessage(BACKUP_ADD);
			}
			cursor.close();


			mCurrent = 1;
			String command = "mkdir -p " + Const.APK_FOLDER;
			System.out.println("command = " + command);
			String ret;
			try {
				ret = Utils.runCommond(process, 1000, command);

				System.out.println("ret = " + ret);

				command = "mkdir -p " + Const.DATA_FOLDER;
				System.out.println("command = " + command);
				ret = Utils.runCommond(process, 1000, command);
				System.out.println("ret = " + ret);

				command = "mkdir -p " + Const.ICON_FOLDER;
				System.out.println("command = " + command);
				ret = Utils.runCommond(process, 1000, command);
				System.out.println("ret = " + ret);

				final Iterator<String> keySet = pathSet.iterator();
				while (keySet.hasNext()) {
					if (!isInterrupted()) {
						final String packageName = keySet.next();
						Utils
								.makeIconFile(getApplicationContext(),
										packageName);

						String path = mApkPath.get(packageName);
						command = "tar -cvf /" + Const.APK_FOLDER + packageName
								+ ".tar" + " " + path;
						System.out.println("command = " + command);
						ret = Utils.runCommond(process, 60 * 1000, command);
						System.out.println("ret = " + ret);

						// command = "tar -cvf /" + Const.DATA_FOLDER +
						// packageName + ".tar" +
						// " /data/data/"
						// + packageName;
						// System.out.println("command = " + command);
						// ret = Utils.runCommond(process, 60 * 1000, command);
						// System.out.println("ret = " + ret);
						if (keySet.hasNext()) {
							handler.sendEmptyMessage(BACKUP_ADD);
						} else {
							handler.sendEmptyMessage(BACKUP_OVER);
						}
					} else {
						handler.sendEmptyMessage(BACKUP_CANCEL);
					}
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
				handler.sendEmptyMessage(BACKUP_CANCEL);
			}
		}
	}

	private class RestoreThread extends Thread {

		@Override
		public void run() {
			super.run();
			System.out.println("RestoreThread.start");
			// 恢复联系人

			int size = contactFiles.size();
			for (int i = 0; i < size; i++) {
				// 首先插入空值，再得到rawContactsId，用于插值
            	mCurreantRestore = i;
				ContentValues values = new ContentValues();
				Uri rawContactUri = getContentResolver().insert(
						RawContacts.CONTENT_URI, values);
				long rawContactsId = ContentUris.parseId(rawContactUri);

				// 往空记录中插入姓名
				values.clear();
				values.put(StructuredName.RAW_CONTACT_ID, rawContactsId);
				values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
				values.put(StructuredName.DISPLAY_NAME, contactFiles.get(i)
						.getName().toString());
				getContentResolver().insert(Data.CONTENT_URI, values);

				// 插入电话
				values.clear();
				values.put(Phone.RAW_CONTACT_ID, rawContactsId);
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				String str = contactFiles.get(i).getPhone().toString();
				String a[] = str.split(",");
				for (int j = 0; j < a.length; j++) {
					values.put(Phone.NUMBER, a[j]);
					Log.d(TAG, "addContactThread:" + j + "num:" + a[j]);
					Log.d(TAG, "addContactThread insert:" + values);
					getContentResolver().insert(Data.CONTENT_URI, values);
				}
				handler.sendEmptyMessage(RESTORE_ADD);
            }

            mCurrent = 1;

			if (mApkNeedRestorePkg.size() == 0) {
				handler.sendEmptyMessage(RESTORE_OVER);
				return;
			}
			for (int i = 0; i < mApkNeedRestorePkg.size(); i++) {
				if (!isInterrupted()) {
					String packageName = mApkNeedRestorePkg.get(i);
					System.out.println("Restore " + packageName);
					String command = "tar -xvf /" + Const.APK_FOLDER
							+ packageName + ".tar";
					String ret;
					try {
						ret = Utils.runCommond(process, 60 * 1000, command);
						System.out.println("Main " + ret);
						command = "pm install -r " + ret;
						ret = Utils.runCommond(process, 60 * 1000, command);
						System.out.println("Main " + ret);
						num++;
						// command = "rm -fr /data/data/" + packageName;
						// ret = Utils.runCommond(process, 1000, command);
						// System.out.println("Main " + ret);

						// command = "tar -xvf /" + Const.DATA_FOLDER +
						// packageName
						// + ".tar";
						// ret = Utils.runCommond(process, 60 * 1000, command);
						// System.out.println("Main " + ret);
						if (i != mApkNeedRestorePkg.size() - 1) {
							handler.sendEmptyMessage(RESTORE_ADD);
							return;
						} else {
							handler.sendEmptyMessage(RESTORE_OVER);
							return;
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
						handler.sendEmptyMessage(RESTORE_CANCEL);
						return;
					}
				} else {
					handler.sendEmptyMessage(RESTORE_CANCEL);
					return;
				}

			}

		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btnBackup:
			mCurrent = 0;
			mIsBackUp = true;
			showDialog(PD_BACKUP);
			thread = new BackupThread();
			thread.start();
			break;
		case R.id.btnRestore:
			num=0;
			mCurrent = 0;
			mIsBackUp = false;
			showDialog(PD_RESTORE);
			thread = new RestoreThread();
			thread.start();
		default:
			break;
		}
	}

	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			long time = System.currentTimeMillis();

			switch (msg.what) {
			case BACKUP_OVER:
				dismissDialog(PD_BACKUP);
				Toast.makeText(getApplicationContext(), "备份完毕",
						Toast.LENGTH_SHORT);
				PrefUtil.setLastBackup(getApplicationContext(), time);
				refresh();
				break;
			case BACKUP_ADD:
				System.out.println("BACKUP_ADD");
				if(mCurrent == 0){
					System.out.println("BACKUP_ADD DATA");
					if(mIsBackUp){
						int size = ContactTFileStore.querySdCounts(getApplicationContext());
						System.out.println("BACKUP_ADD DATA size:" + size);
						pd.setMessage(getResources().getString(R.string.backup_1));
						pd.setProgress(size);
					}else{
						pd.setProgress(mCurreantRestore);
					}
				}else if(mCurrent == 1){
					if(mIsBackUp){
						pd.setMessage(getResources().getString(R.string.backup));
						pd.setMax(mApkPath.size());
					}else{
						pd.setMax(mApkNeedRestorePkg.size());
					}
					File file = new File(Const.APK_FOLDER);
					String[] apkBackPkg = null;
					if (file.exists()) {
						apkBackPkg = file.list();
						pd.setProgress(apkBackPkg.length);
					}
				}
				break;
			case BACKUP_ERROR:
				PrefUtil.setLastBackup(getApplicationContext(), time);
				System.out.println("BACKUP_ERROR");
				break;
			case BACKUP_CANCEL:
				System.out.println("BACKUP_CANCLE");
				dismissDialog(PD_CANCEL);
				PrefUtil.setLastBackup(getApplicationContext(), time);
				Toast.makeText(getApplicationContext(), "取消成功",
						Toast.LENGTH_SHORT);
				refresh();
				break;
			case RESTORE_OVER:
				dismissDialog(PD_RESTORE);
				Toast.makeText(getApplicationContext(), "还原完毕",
						Toast.LENGTH_SHORT);
				refresh();
				break;
			case RESTORE_ADD:
				System.out.println("RESTORE_ADD");
				Log.d(TAG, "RESTORE_ADD mCurrent:" + mCurrent);
				if(mCurrent == 0) {
					pd.setMessage(getResources().getString(R.string.restore_1));

					pd.setProgress(mCurreantRestore);
				} else if(mCurrent == 1) {
					pd.setMessage(getResources().getString(R.string.restore));
					pd.setProgress(num);
					pd.setMax(mApkNeedRestorePkg.size());
				}
				break;
			case RESTORE_ERROR:
				System.out.println("RESTORE_ERROR");
				break;
			case RESTORE_CANCEL:
				System.out.println("RESTORE_CANCLE");
				dismissDialog(PD_CANCEL);
				Toast.makeText(getApplicationContext(), "取消成功",
						Toast.LENGTH_SHORT);
				refresh();
				break;
			case BACKUP_BEGAIN:
				dismissDialog(PD_RUNGNING);
				break;
			default:
				break;
			}
		}
	};

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case PD_BACKUP:
			pd = new MyPb(this);
			pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			pd.setMessage(getString(R.string.backup_1));
			ContentResolver contentResolver = getContentResolver();
			Cursor cursor = contentResolver.query(
					ContactsContract.Contacts.CONTENT_URI, null, null, null,
					null);
			mContactCount = cursor.getCount();
			pd.setMax(mContactCount);
			return pd;
		case PD_RESTORE:
			pd = new MyPb(this);
			pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			pd.setMessage(getString(R.string.restore_1));
			contactFiles = new ArrayList<ContactTVo>();
            contactFiles = ContactTFileStore.queryAllFromSd(getApplicationContext());
			pd.setMax(contactFiles.size());
			return pd;
		case PD_CANCEL:
			pd = new MyPb(this);
			pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			pd.setMessage(getString(R.string.cancel));
			pd.setCancelable(false);
			return pd;
		case PD_RUNGNING:
			pd = new MyPb(this);
			pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			pd.setMessage(getString(R.string.runing));
			pd.setCancelable(false);
			return pd;
		default:
			return super.onCreateDialog(id);
		}
	}

	private class MyPb extends ProgressDialog {

		public MyPb(Context context) {
			super(context);
		}

		@Override
		public void onBackPressed() {
			showDialog(PD_CANCEL);
			thread.interrupt();
			super.onBackPressed();
		}

		@Override
		public boolean onSearchRequested() {
			// 禁止搜索键
			return true;
		}
	}

	private void refresh() {
		// 已备份的应用列表
		File file = new File(Const.APK_FOLDER);
		String[] apkBackPkg = null;
		if (file.exists()) {
			apkBackPkg = file.list();
			for (int i = 0; i < apkBackPkg.length; i++) {
				String apkPkg = apkBackPkg[i].split(".tar")[0];
				apkBackPkg[i] = apkPkg;
				System.out.println("已备份: " + apkPkg);
			}
		}
		if (apkBackPkg == null) {
			tvBackup.setText("还木有备份应用");
		} else {
			List<String> apkNeedRestorePkg = new ArrayList<String>();
			for (int i = 0; i < apkBackPkg.length; i++) {
				String packageName = apkBackPkg[i];
				// 如果已安装应用列表中包含已备份的应用，则不安装
				if (!mApkPath.containsKey(packageName)) {
					apkNeedRestorePkg.add(packageName);
				}
			}

			tvBackup.setText("已备份了" + apkBackPkg.length + "款应用，其中有"
					+ apkNeedRestorePkg.size() + "款未安装需要恢复");
			// if (apkNeedRestorePkg.size() == 0) {
			// btnRestore.setClickable(false);
			// }
			
		}
		long backupTime = PrefUtil.getLastBackup(getApplicationContext());
		if (backupTime != 0) {
			Date date = new Date(backupTime);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			tvLastBackTime.setText("上次备份时间：" + sdf.format(date));
		} else {
			tvLastBackTime.setText("无法获取上次备份时间，建议您立即备份");
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		isRunning = false;
	}
}